package com.jg.poiet.policy;

import com.jg.poiet.NiceXSSFWorkbook;
import com.jg.poiet.XSSFTemplate;
import com.jg.poiet.data.CellRenderData;
import com.jg.poiet.data.ListRenderData;
import com.jg.poiet.data.RowRenderData;
import com.jg.poiet.data.TemplateListRenderData;
import com.jg.poiet.template.cell.CellTemplate;
import com.jg.poiet.util.PatternUtil;
import com.jg.poiet.util.StyleUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 模板列表处理
 */
public class TemplateListRenderPolicy extends AbstractRenderPolicy<TemplateListRenderData> {

    @Override
    protected boolean validate(TemplateListRenderData data) {
        return data.getRow() >= 0 && data.getColumn() >= 0;
    }

    @Override
    public void doRender(CellTemplate cellTemplate, TemplateListRenderData data, XSSFTemplate template) {
        XSSFCell cell = cellTemplate.getCell();
        Helper.renderTemplateList(template, cell, data);
    }

    public static class Helper {

        /**
         * 渲染模板列表数据
         * @param template template
         * @param cell  cell
         * @param data data
         */
        public static void renderTemplateList(XSSFTemplate template, XSSFCell cell, TemplateListRenderData data) {
            if (data.getDirection() == TemplateListRenderData.DIRECTION.HORIZONTAL) {   //水平方向
                renderHorizontalList(template, cell, data);
            } else if (data.getDirection() == TemplateListRenderData.DIRECTION.VERTICAL) {  //垂直方向
                renderVerticalList(template, cell, data);
            }
        }

        /**
         * 渲染水平方向列表数据
         * @param template  template
         * @param cell  cell
         * @param listData  listData
         */
        private static void renderHorizontalList(XSSFTemplate template, XSSFCell cell, TemplateListRenderData listData) {
            NiceXSSFWorkbook workbook = template.getXSSFWorkbook();
            XSSFSheet sheet = cell.getSheet();
            cell.setCellValue("");  //将该单元格值置空
            if (listData.getListData().size() == 0) {
                return ;
            }
            String gramerPrefix = PatternUtil.toPatternStr(template.getConfig().getGramerPrefix());
            String gramerSuffix = PatternUtil.toPatternStr(template.getConfig().getGramerSuffix());
            Pattern pattern = Pattern.compile("^" + gramerPrefix + "([\\s\\S]+)" + gramerSuffix + "$");
            int firstRow = cell.getRowIndex();
            int lastRow = firstRow + listData.getRow();
            int firstCol = cell.getColumnIndex();
            int lastCol = firstCol + listData.getColumn();
            int index = 0;
            int currCol = firstCol;
            for (Map<String, CellRenderData> mapData: listData.getListData()) {
                if (index != 0) {
                    for (int i = firstRow; i <= lastRow; i++) {
                        XSSFRow row = sheet.getRow(i);
                        if (row == null) {
                            continue;
                        }
                        for (int j = currCol; j <= currCol + listData.getColumn(); j++) {
                            XSSFCell oldCell = row.getCell(j - currCol + firstCol);
                            if (oldCell == null) {
                                continue;
                            }
                            XSSFCell newCell = row.createCell(j);
                            newCell.copyCellFrom(oldCell, new CellCopyPolicy());
                            sheet.setColumnWidth(newCell.getColumnIndex(), sheet.getColumnWidth(oldCell.getColumnIndex()));
                        }
                    }
                }
                index++;
                currCol += listData.getColumn() + 1;
            }
            currCol = firstCol;
            for (Map<String, CellRenderData> mapData: listData.getListData()) {
                for (int i = firstRow; i <= lastRow; i++) {
                    XSSFRow row = sheet.getRow(i);
                    if (row == null) {
                        continue;
                    }
                    for (int j = currCol; j <= currCol + listData.getColumn(); j++) {
                        XSSFCell newCell = row.getCell(j);
                        if (newCell == null || CellType.STRING != newCell.getCellType()) {
                            continue;
                        }
                        String value = newCell.getStringCellValue();
                        Matcher matcher = pattern.matcher(value);
                        if (matcher.find()) {
                            String key = matcher.group(1);
                            CellRenderData cellRenderData = mapData.get(key);
                            if (cellRenderData != null) {
                                TextRenderPolicy.Helper.renderTextCell(newCell, cellRenderData.getRenderData(), template);
                            }
                        }
                    }
                }
                currCol += listData.getColumn() + 1;
            }
        }


        /**
         * 渲染垂直方向列表
         * @param template  template
         * @param cell  cell
         * @param listData  listData
         */
        private static void renderVerticalList(XSSFTemplate template, XSSFCell cell, TemplateListRenderData listData) {
            NiceXSSFWorkbook workbook = template.getXSSFWorkbook();
            XSSFSheet sheet = cell.getSheet();
            cell.setCellValue("");  //将该单元格值置空
            if (listData.getListData().size() == 0) {
                return ;
            }
            String gramerPrefix = PatternUtil.toPatternStr(template.getConfig().getGramerPrefix());
            String gramerSuffix = PatternUtil.toPatternStr(template.getConfig().getGramerSuffix());
            Pattern pattern = Pattern.compile("^" + gramerPrefix + "([\\s\\S]+)" + gramerSuffix + "$");
            int firstRow = cell.getRowIndex();
            int lastRow = firstRow + listData.getRow();
            int firstCol = cell.getColumnIndex();
            int lastCol = firstCol + listData.getColumn();
            Map<String, XSSFRow> rowMap = new HashMap<>();
            for (int i = firstRow; i <= lastRow; i++) {
                XSSFRow row = sheet.getRow(i);
                rowMap.put((i - firstRow) + "", row);
            }
            insertRow(workbook, cell, listData);   //插入行
            int index = 0;
            int currRow = firstRow;
            for (Map<String, CellRenderData> mapData: listData.getListData()) {
                if (index != 0) {
                    for (int i = currRow; i <= currRow + listData.getRow(); i++) {
                        XSSFRow newRow = sheet.getRow(i);
                        if (newRow == null) {
                            newRow = sheet.createRow(i);
                        }
                        XSSFRow copyRow = rowMap.get((i - currRow) + "");
                        if (copyRow == null) {
                            continue;
                        }
                        newRow.copyRowFrom(copyRow, new CellCopyPolicy());
                        if (copyRow.getZeroHeight()) {
                            newRow.setZeroHeight(true);
                        } else {
                            newRow.setHeightInPoints(copyRow.getHeightInPoints());
                        }
                    }
                }
                index++;
                currRow += listData.getRow() + 1;
            }
            currRow = firstRow;
            for (Map<String, CellRenderData> mapData: listData.getListData()) {
                for (int i = currRow; i <= currRow + listData.getRow(); i++) {
                    XSSFRow newRow = sheet.getRow(i);
                    if (newRow == null) {
                        newRow = sheet.createRow(i);
                    }
                    for (int j = firstCol; j <= lastCol; j++) {
                        XSSFCell newCell = newRow.getCell(j);
                        if (newCell == null || CellType.STRING != newCell.getCellType()) {
                            continue;
                        }
                        String value = newCell.getStringCellValue();
                        Matcher matcher = pattern.matcher(value);
                        if (matcher.find()) {
                            String key = matcher.group(1);
                            CellRenderData cellRenderData = mapData.get(key);
                            if (cellRenderData != null) {
                                TextRenderPolicy.Helper.renderTextCell(newCell, cellRenderData.getRenderData(), template);
                            }
                        }
                    }
                }
                currRow += listData.getRow() + 1;
            }
            template.getXSSFWorkbook().updateCellRangeAddress();
        }

        /**
         * 插入行
         * @param workbook  workbook
         * @param cell  cell
         * @param listData listData
         */
        private static void insertRow(NiceXSSFWorkbook workbook, XSSFCell cell, TemplateListRenderData listData) {
            if (listData.getListData().size() <= 1) {
                return ;
            }
            XSSFRow lastRow = cell.getSheet().getRow(cell.getRowIndex() + listData.getRow());
            if (lastRow == null) {
                lastRow = cell.getSheet().createRow(cell.getRowIndex() + listData.getRow());
            }
            XSSFCell lastCell = lastRow.getCell(cell.getColumnIndex());
            if (lastCell == null) {
                lastCell = lastRow.createCell(cell.getColumnIndex());
            }
            int insertNum = (listData.getListData().size() - 1) * (listData.getRow() + 1);
            PolicyHelper.insertRow(workbook, lastCell, insertNum - 1);
        }
    }

}
